package com.cskaoyan.javase.oop2._1extends._7initialization._2detail;

/**
 * 细节问题/注意事项:
 *      1.(重点)创建一个子类对象,无论如何,都要先执行父类构造器
 *          那么如果父类没有默认无参,子类就不支持隐式的子类对象初始化
 *          这种情况下:
 *              a.要么给父类加上默认无参
 *              b.要么子类就必须进行显式的子类对象初始化,直接用
 *                  super调用父类已存在的构造器
 *          如果一个类需要创建对象,给这个类加上无参构造是一个好习惯,原因在于:
 *              a.子类对象隐式初始化需要依赖于父类无参构造器
 *              b.(扩展)后续的框架阶段,利用框架创建对象.
 *                  某些情况下依赖于该类的无参构造器
 *
 *       2.存在继承时,子类的构造器的写法第一行就可以用super指向父类构造器了
 *          那么alt + insert自动生成构造器时,相应的选项也会有所变化.
 *          课下自己练习一下即可
 *
 *       3.(重点)构造器的作用是赋值,在子类对象初始化过程中,这一点就得以体现了
 *          创建子类对象时,父类构造器也执行了
 *          但显然没有创建父类对象
 *          构造器不是用来创建对象的,构造器是用来给自身成员变量赋值的.
 *          总结一下构造器的赋值作用:
 *              a.创建自身对象,给自身成员变量赋值
 *              b.创建子类对象,在这种情况下,调用父类构造器,给父类成员变量赋值
 *
 *       4.super在表示调用父类构造器时,语法是super(实参)
 *         this在表示调用自身构造器时,语法是this(实参)
 *         它们两在子类构造器中,都可以用来表示调用其它构造器
 *         而且都必须在构造器代码的第一行
 *         所以它们两个关键字,在表示调用构造器时,是不能混用的
 *
 *       5.任何构造器的第一行,必然存在this/super去调用别的构造器
 *          如果没有明确写出来
 *          那么就隐含super();
 *
 * @since 10:49
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
}
class Animal{
    int age;
    String name;

    public Animal() {
    }

    public Animal(String name) {
        this.name = name;
    }

    public Animal(int age, String name) {
        this.age = age;
        this.name = name;
    }
}
class Cat extends Animal{
    double price;
    public Cat() {
    }

    public Cat(String name, double price) {
       // Call to 'super()' must be first statement in constructor body
        super(name);
        this.price = price;
    }

    public Cat(int age, String name, double price) {
        super(age, name);
        this.price = price;
    }
}


class Father {
    int num;

    public Father(int num) {
        this.num = num;
    }

}
// There is no default constructor available in 'com.cskaoyan.javase.oop2._1extends._7initialization._2detail.Father' 父类没有默认无参来支持子类完成隐式的子类对象初始化
class Son extends Father{
    public Son(int num) {
        super(num);
    }
}